import os
import subprocess
import path
import translation
import numpy as np
import time
import laspy

# 定义BLH坐标基准点
target_blh = (40, 23, 30.19211, 'N', 115, 54, 43.52697, 'E', 496.885)
    
def convert_pcd_to_las(input_file, output_file):
    """
    使用CloudCompare将PCD文件转换为LAS文件

    参数:
    input_file (str): 输入的PCD文件路径
    output_file (str): 输出的LAS文件路径
    """
    # 调用shell文件并传入参数
    command = ["./convert_pcd_to_las.sh", input_file, output_file]
    if not os.path.isfile(command[0]):
        print(f"Error: {command[0]} not found.")
        return
    result = subprocess.run(command, capture_output=True, text=True)
    if result.returncode != 0:
        print(f"Error processing {input_file} to {output_file}")
        print("stderr:", result.stderr)
    else:
        print(f"Successfully processed {input_file} to {output_file}")
        print("stdout:", result.stdout)

def translate_order(input_file, output_file, translation_vector):
    try:
        # CloudCompare 命令行路径（根据你的安装路径修改）
        cc_path = "/snap/bin/cloudcompare.CloudCompare"
        txt_path = "/home/gjm/Pcd2Las/src/pcd2las_python/config/translation.txt"
        
        # 构造 CloudCompare 的命令
        command = [
            cc_path,
            "-SILENT",
            "-NO_TIMESTAMP",  # 禁用时间戳
            "-O", input_file,
            "-APPLY_TRANS", "FILE", txt_path,
            "-SAVE_CLOUDS", "FILE", output_file
        ]


        # 执行命令
        result = subprocess.run(command, capture_output=True, text=True)

        # 检查执行结果
        if result.returncode == 0:
            print(f"点云成功平移并保存至: {output_file}")
        else:
            print(f"CloudCompare 命令执行失败: {result.stderr}")

    except Exception as e:
        print(f"运行 CloudCompare 时出错: {e}")


def run():
    # 读取path中的路径和文件名称,
    while True:
        latest_pcd_file = path.get_latest_pcd_file(path.input_folder)
        # 如果两次的文件名相同, 则说明没有新的PCD文件产生
        if latest_pcd_file == path.last_pcd_file:
            # print("没有新的PCD文件产生")
            continue
        else:
            path.last_pcd_file = latest_pcd_file
        if latest_pcd_file:
            # print(f"最新的PCD文件是: {latest_pcd_file}")
            # 调用CloudCompare将PCD文件转换为LAS文件
            # 输出文件名为PCD文件名+'.las'
            output_file = path.output_folder + '/' + path.file_name + '.las'
            output_file_translated = path.output_folder + '/' + path.file_name + '_translated.las'
            # print(f"输出的LAS文件名: {output_file}")
            convert_pcd_to_las(latest_pcd_file, output_file) 

            return
            # time.sleep(12)
            # translate_vector = (100, 200, 300)  # 平移向量 (Δx, Δy, Δz)
            # translate_order(output_file, output_file_translated, translate_vector)
            # # 计算平移向量
            # return
            translation_vector = translation.compute_translation_vector(target_blh)
            # print(f"计算的平移向量为: {translation_vector}")

            with laspy.open(output_file) as input_las:
                point_cloud = input_las.read()
                # header = input_las.header
                #  # 打印缩放因子和偏移量
                # print(f"X轴缩放因子: {header.scales[0]}")
                # print(f"Y轴缩放因子: {header.scales[1]}")
                # print(f"Z轴缩放因子: {header.scales[2]}")
                
                # print(f"X轴偏移量: {header.offsets[0]}")
                # print(f"Y轴偏移量: {header.offsets[1]}")
                # print(f"Z轴偏移量: {header.offsets[2]}")

                # # 打印文件内坐标范围
                # print(f"X轴范围: {header.mins[0]} - {header.maxs[0]}")
                # print(f"Y轴范围: {header.mins[1]} - {header.maxs[1]}")
                # print(f"Z轴范围: {header.mins[2]} - {header.maxs[2]}")

                # return
                # 可能需要变换因子值后，将偏移值倒进去，再变回去
                try:
                    # 提取原始点云的 (x, y, z) 坐标并进行平移
                    points = np.vstack((point_cloud.x, point_cloud.y, point_cloud.z)).T
                     # 临时放大缩放因子为 1.0，防止平移过程中的溢出
                    header = input_las.header
                    original_scale = header.scale
                    header.scale = [1.0, 1.0, 1.0]  # 临时缩放为1.0
                    # 执行平移
                    translated_points = points + translation_vector                     
                    # 创建新的 LAS 点云对象
                    new_point_cloud = laspy.LasData(header)
                     # 确保坐标在 int32 范围内，并赋值到新点云
                    new_point_cloud.x = np.clip(translated_points[:, 0], -2**31, 2**31 - 1).astype(np.int32)
                    new_point_cloud.y = np.clip(translated_points[:, 1], -2**31, 2**31 - 1).astype(np.int32)
                    new_point_cloud.z = np.clip(translated_points[:, 2], -2**31, 2**31 - 1).astype(np.int32)
                    # 更新偏移量以适应新的坐标范围
                    min_x, min_y, min_z = translated_points.min(axis=0)
                    new_point_cloud.header.offset = [min_x, min_y, min_z]                   
                    # 恢复原始的缩放因子
                    new_point_cloud.header.scale = original_scale
                    # 保存平移后的点云为新的 .las 文件
                    new_point_cloud.write(output_file)
                    print(f"Scale: {new_point_cloud.header.scale}")
                    print(f"Offset: {new_point_cloud.header.offset}")
                    print(f"Translated X Range: {translated_points[:, 0].min()} - {translated_points[:, 0].max()}")
                    print(f"X轴缩放因子: {new_point_cloud.header.scales[0]}")
                    print(f"Y轴缩放因子: {new_point_cloud.header.scales[1]}")
                    print(f"Z轴缩放因子: {new_point_cloud.header.scales[2]}")
                    print(f"X轴偏移量: {new_point_cloud.header.offsets[0]}")
                    print(f"Y轴偏移量: {new_point_cloud.header.offsets[1]}")
                    print(f"Z轴偏移量: {new_point_cloud.header.offsets[2]}")
                    print(f"X轴范围: {new_point_cloud.header.mins[0]} - {new_point_cloud.header.maxs[0]}")
                    print(f"Y轴范围: {new_point_cloud.header.mins[1]} - {new_point_cloud.header.maxs[1]}")
                    print(f"Z轴范围: {new_point_cloud.header.mins[2]} - {new_point_cloud.header.maxs[2]}")
                    print(f"平移后的点云已保存至 {output_file}")
                except OverflowError as e:
                    print(f"赋值时发生溢出错误: {e}")
                # 这里可以添加更多的错误处理代码，比如记录错误信息等
                except Exception as e:
                    print(f"运行时发生其他错误: {e}") 
            
            return

            # 读取转换后的las文件
            sent_las_name = os.path.join(output_file, f"{output_file}")
            destination = "ubuntu@82.157.253.245:/home/ubuntu/cloudData/"
            command = f"sshpass -p '9;s/6xB7Q2mZ~' rsync -avz {sent_las_name} {destination}"
            # 使用 subprocess.call() 调用 rsync 命令
            result = subprocess.call(command, shell=True)
            
            # 检查命令是否成功执行
            if result != 0:
                print("rsync failed")
        else:
            print("没有找到任何PCD文件")
    

if __name__ == '__main__':
    # current_directory = os.getcwd()
    # print(f"当前路径是: {current_directory}")
    os.chdir("../shell")
    # new_directory = os.getcwd()
    # print(f"跳转后的工作目录: {new_directory}")
    run()
    # output_file ='/home/gjm/Pcd2Las/src/output/1725438797.las'
    # output_file_translated = '/home/gjm/Pcd2Las/src/output/1725438797_translated.las'

    # translate_vector = (100, 200, 300)  # 平移向量 (Δx, Δy, Δz)
    # translate_order(output_file, output_file_translated, translate_vector)
    